package parsexml;

import org.dom4j.*;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import parsexml.constant.XmlNodeConstant;
import parsexml.enity.XmlClass;
import parsexml.enity.XmlStudent;
import parsexml.enity.XmlSubject;

import java.io.*;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

/**
 * @author 李栋
 * @version 1.0.0
 * @className ParseXmlTest.java
 * @createTime 2021年07月14日 20:22:00
 */
public class ParseXmlByDom4jTest {

    private static final Logger logger = LoggerFactory.getLogger(ParseXmlByDom4jTest.class);


    public InputStream getInputStream() throws FileNotFoundException {
        File file = new File("K:\\JavaTest\\src\\main\\java\\parsexml\\ClassDemo.xml");
        return new FileInputStream(file);
    }


    /**
     * Dom 4j 方式解析
     */
    @Test
    public void parseXmlByDom4j() {
        //1.创建Reader对象
        SAXReader reader = new SAXReader();
        //2.加载xml
        Document document = null;
        InputStream inputStream = null;
        try {
            inputStream = getInputStream();
            document = reader.read(getInputStream());
            logger.info("拿到 Document 对象");
        } catch (DocumentException | FileNotFoundException e) {
            logger.error(" XML 文件解析为 Document 对象出错:{}", e.getMessage(), e);
        } finally {
            if (Objects.nonNull(inputStream)) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    logger.error("Error Occur:{}", e.getMessage());
                }
            }
        }
        Objects.requireNonNull(document, "xml解析对象为空");
        XmlClass xmlClass = new XmlClass();
        parseXmlByDom4j(document, xmlClass);
        logger.info("解析完成！");
    }

    /**
     * 解析 xml 使用 Dom4j
     *
     * @param document
     * @param xmlClass
     */
    private void parseXmlByDom4j(Document document, XmlClass xmlClass) {
        //3.获取根节点
        Element rootElement = document.getRootElement();
        Iterator<Element> elementIterator = rootElement.elementIterator();
        while (elementIterator.hasNext()) {
            Element element = elementIterator.next();
            Iterator<Element> childElementIterator = element.elementIterator();
            while (childElementIterator.hasNext()) {
                Element childElement = childElementIterator.next();
                String name = childElement.getName();
                String stringValue = childElement.getStringValue();
                if (XmlNodeConstant.CLASS_CNO.equalsIgnoreCase(name)) {
                    xmlClass.setClassCno(stringValue);
                }
                if (XmlNodeConstant.CLASS_NAME.equalsIgnoreCase(name)) {
                    xmlClass.setClassName(stringValue);
                }
                // 解决表
                if (XmlNodeConstant.STUDENT.equalsIgnoreCase(name)) {
                    XmlStudent xmlStudent = new XmlStudent();
                    packageXmlStudent(childElement.content(), xmlStudent);
                    xmlClass.getXmlStudents().add(xmlStudent);
                }
            }
        }
    }

    /**
     * 组装学生信息
     *
     * @param content
     * @param xmlStudent
     */
    private void packageXmlStudent(List<Node> content, XmlStudent xmlStudent) {
        for (Node studentNode : content) {
            String tableNodeName = studentNode.getName();
            String tableNodeStringValue = studentNode.getStringValue();
            if (XmlNodeConstant.STUDENT_SNO.equalsIgnoreCase(tableNodeName)) {
                xmlStudent.setSno(tableNodeStringValue);
            }
            if (XmlNodeConstant.NAME.equalsIgnoreCase(tableNodeName)) {
                xmlStudent.setName(tableNodeStringValue);
            }
            if (XmlNodeConstant.GENDER.equalsIgnoreCase(tableNodeName)) {
                xmlStudent.setGender(tableNodeStringValue);
            }
            if (XmlNodeConstant.SUBJECT.equalsIgnoreCase(tableNodeName)) {
                XmlSubject xmlSubject = new XmlSubject();
                packageXmlSubject(studentNode, xmlSubject);
                xmlStudent.getXmlSubjects().add(xmlSubject);
            }

        }
    }

    /**
     * 组装科目信息
     *
     * @param studentNode
     * @param xmlSubject
     */
    private void packageXmlSubject(Node studentNode, XmlSubject xmlSubject) {
        List<Node> subjectNodes = ((Branch) studentNode).content();
        for (Node subjectNode : subjectNodes) {
            String columnNodeName = subjectNode.getName();
            String columnNodeString = subjectNode.getStringValue();
            if (XmlNodeConstant.NAME.equalsIgnoreCase(columnNodeName)) {
                xmlSubject.setSubjectName(columnNodeString);
            }
            if (XmlNodeConstant.SUBJECT_NO.equalsIgnoreCase(columnNodeName)) {
                xmlSubject.setSubjectNo(columnNodeString);
            }
            if (XmlNodeConstant.SCORE.equalsIgnoreCase(columnNodeName)) {
                xmlSubject.setScore(Float.parseFloat(columnNodeString));
            }
        }
    }
}
